robotbattlefandomcom-20200213-history
MultiMode 101
Introduction Multi-Mode robots have two or more separate modes that they can switch between. A good multi-mode robot will attempt to learn which mode is better. In this tutorial we will be merging two simple robots together. Here are the source robots: Init{ name("SittingDuck") author("GNU FDL") regcore(core) regdtcrobot(FoundBot, 1) regascan(autoscan, 2) lockgun(_true) //Lock the gun to the radar } Core{ bodyleft(5) } FoundBot{ stop() fire(5) continue() } autoscan{ scan() } Init{ name("CookieGuy") author("GNU FDL") regcore(core) regdtccookie(FoundCookie, 1) regascan(autoscan, 2) } Core{ radarleft(5) } FoundCookie{ stop() syncall() ahead(_scandist+5) continue() } AutoScan{ scan() } Rename Sections Because were are merging the robots into one file, rename the sections. There are a few advantages to this but mostly it's so you can identify which sections come from which robot. Don't do the init section yet. We'll come to that in a minute. For this example: SittingDuck * Core becomes Duck_Core * FoundBot becomes Duck_FoundBot CookieGuy * Core becomes Guy_Core * FoundCookie becomes Guy_FoundCookie Since both autoscan procedures are identical we only need one copy. * AutoScan stays the same. Merge the inits Next we need to merge the two inits together. Basically we need to create a switch between the two init procedures. We can do this with an if statement: init{ if(switch) //First init else //Second init endif } Now, if switch is true then the first init will be run and if it is false the second will be run. Here it is for the example robots: init{ name("MultiMode 101") if (switch) //SittingDuck Init regcore(Duck_core) regdtcrobot(Duck_FoundBot, 1) regascan(autoscan, 2) lockgun(_true) //Lock the gun to the radar else //CookieGuy Init regcore(Guy_core) regdtccookie(Guy_FoundCookie, 1) regascan(autoscan, 2) endif } Things to remember when doing this: * Make sure you update the register commands so they point to the renamed sections * You can only call , and once per bot, so you don't need to include those commands. * As well as the register commands remember to include any other setup commands you used such as , etc. Switching Modes and Learning Right, now we have a robot that can switch between two modes. But how does your robot decide which mode to use? Well, you are going to have to write a learning routine. The following example is a very basic learning routine, but you can improve it once you know what it does. We are going to write this routine in the section. This section gets called if your robot gets killed or wins the game. This simple example figures out if we won or lost: dead{ if (_energy > 0) //If we still have energy left, we must of won or drew the game else //If we have no energy, we lost the game endif } Learning What we are going to do is keep track of the wins and losses of each mode. Then we are going to make the robot choose the mode with the most wins. Do you remember the switch variable? We are going to need to use it again. Remember, if it's true, we're in SittingDuck mode, if it's false we're in CookieGuy mode. dead{ if (switch) //SittingDuck Mode if (_energy > 0) DuckScore= DuckScore + 1 //Increase the score else DuckScore= DuckScore - 1 //Decrease the score endif else //CookieGuy Mode if (_energy > 0) GuyScore= GuyScore + 1 //Increase the score else GuyScore= GuyScore - 1 //Decrease the score endif endif } Switching Modes So, DuckScore and GuyScore represent how well each mode has done. We can now select between them: if (GuyScore > DuckScore) //CookieGuy has the high score switch = _false else //SittingDuck has the high score switch = _true endif Storing Variables We have one last problem: Normally at the end of a game all your robots variables are reset to zero. We can avoid this by using the command on variables we need to keep: store(switch) store(GuyScore) store(DuckScore) The finished product That's it! Finally here's the combined example robot in all its glory: init{ name("MultiMode 101") author("GNU FDL") if (switch) //SittingDuck Init regcore(Duck_core) regdtcrobot(Duck_FoundBot, 1) regascan(autoscan, 2) lockgun(_true) //Lock the gun to the radar else //CookieGuy Init regcore(Guy_core) regdtccookie(Guy_FoundCookie, 1) regascan(autoscan, 2) endif } dead{ if (switch) //SittingDuck Mode if (_energy > 0) DuckScore= DuckScore + 1 //Increase the score else DuckScore= DuckScore - 1 //Decrease the score endif else //CookieGuy Mode if (_energy > 0) GuyScore= GuyScore + 1 //Increase the score else GuyScore= GuyScore - 1 //Decrease the score endif endif if (GuyScore > DuckScore) //CookieGuy has the high score switch = _false else //SittingDuck has the high score switch = _true endif store(switch) store(GuyScore) store(DuckScore) } Duck_Core{ bodyleft(5) } Duck_FoundBot{ stop() fire(5) continue() } Guy_Core{ radarleft(5) } Guy_FoundCookie{ stop() syncall() ahead(_scandist+5) continue() } autoscan{ scan() } Category:Tutorials